﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;


/************************************************************************
 * 项目名称 :  Sorting.App.Controls  
 * 项目描述 :     
 * 类 名 称 :  MessageBoxHelper
 * 版 本 号 :  v1.0.0.0 
 * 说    明 :     
 * 作    者 :  Lewis
 * 创建时间 :  2022/5/20 10:36:17
 * 更新时间 :  2022/5/20 10:36:17
************************************************************************/
namespace Sorting.App.Controls
{
    public class MyMessageBox
    {
        /// <summary>
        /// 结果按钮
        /// </summary>
        public enum MessageBoxResultButton
        {
            Yes,
            No,
            Cancel
        }
        /// <summary>
        /// 结果
        /// </summary>
        public class MessageBoxResult
        {
            /// <summary>
            /// 结果按钮
            /// </summary>
            public MessageBoxResultButton Button { get; set; }
            /// <summary>
            /// Yes剩余时间
            /// </summary>
            public TimeSpan? YesLeftTime { get; set; }
            /// <summary>
            /// No剩余时间
            /// </summary>
            public TimeSpan? NoLeftTime { get; set; }
        }
        /// <summary>
        /// 业务数据对象
        /// </summary>
        public class MessageBoxDataContext : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            /// <summary>
            /// 消息框的标题
            /// </summary>
            public string Title
            {
                get { return _title; }
                set { _title = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Title")); }
            }
            /// <summary>
            /// 消息框的文本内容
            /// </summary>
            public string Context
            {
                get { return _context; }
                set { _context = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Context")); }
            }
            /// <summary>
            /// Yes按钮的文本
            /// </summary>
            public string YesText
            {
                get { return _yesText; }
                set { _yesText = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("YesText")); }
            }
            /// <summary>
            /// No按钮的文本
            /// </summary>
            public string NoText
            {
                get { return _noText; }
                set { _noText = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("NoText")); }
            }
            /// <summary>
            /// Yes选项剩余时间
            /// </summary>
            public TimeSpan? YesLeftTime
            {
                get { return _yesLeftTime; }
                set { _yesLeftTime = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("YesLeftTime")); }
            }
            /// <summary>
            /// No选项剩余时间
            /// </summary>
            public TimeSpan? NoLeftTime
            {
                get { return _noLeftTime; }
                set { _noLeftTime = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("NoLeftTime")); }
            }
            /// <summary>
            /// No按钮命令
            /// </summary>
            public ICommand NoCommand
            {
                get { return _noCommand; }
                set { _noCommand = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("NoCommand")); }
            }
            /// <summary>
            /// Yes按钮命令
            /// </summary>
            public ICommand YesCommand
            {
                get { return _yesCommand; }
                set { _yesCommand = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("YesCommand")); }
            }
            /// <summary>
            ///Cancel按钮命令
            /// </summary>
            public ICommand CancelCommand
            {
                get { return _cancleCommand; }
                set { _cancleCommand = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CancelCommand")); }
            }

            /// <summary>
            ///结果
            /// </summary>
            public MessageBoxResult Result { internal set; get; }
            /// <summary>
            /// 倒计时的时钟
            /// </summary>
            internal DispatcherTimer Timer { set; get; }
            string _title = "tips";
            string _context = "Ensure?";
            string _yesText = "Yes";
            string _noText = "No";
            TimeSpan? _yesLeftTime;
            TimeSpan? _noLeftTime;
            ICommand _noCommand;
            ICommand _yesCommand;
            ICommand _cancleCommand;
        }

        public class MessageBoxHelper
        {
            class Command : ICommand
            {
                Action<object> _action;
                public Command(Action<object> action)
                {
                    _action = action;
                }
                public event EventHandler CanExecuteChanged;

                public bool CanExecute(object parameter)
                {
                    return true;
                }
                public void Execute(object parameter)
                {
                    _action(parameter);
                }
            }
            /// <summary>
            ///toast弹出消息
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <param name="stayTime">停留时间</param>
            public static void Toast<T>(string context, TimeSpan stayTime) where T : Window, new()
            {
                Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    ShowDialog<T>(null, context, null, null, stayTime, null, false);
                }));
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string context) where T : Window, new()
            {
                return ShowDialog<T>(null, context, "确定", null, null, null, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context) where T : Window, new()
            {
                return ShowDialog<T>(title, context, "确定", null, null, null, false);
            }

            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText) where T : Window, new()
            {
                return ShowDialog<T>(title, context, yesText, null, null, null, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText, bool isCancelable) where T : Window, new()
            {
                return ShowDialog<T>(title, context, yesText, null, null, null, isCancelable);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText, string noText) where T : Window, new()
            {
                return ShowDialog<T>(title, context, yesText, noText, null, null, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText, string noText, bool isCancelable) where T : Window, new()
            {
                return ShowDialog<T>(title, context, yesText, noText, null, null, isCancelable);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string context, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return ShowDialog<T>(null, context, null, null, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return ShowDialog<T>(null, context, yesText, noText, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return ShowDialog<T>(title, context, yesText, noText, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 显示消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>结果</returns>
            public static MessageBoxResult ShowDialog<T>(string title, string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown, bool isCancelable) where T : Window, new()
            {

                var mb = Create<T>(title, context, yesText, noText, yestCountDown, noCountDown, isCancelable);
                mb.ShowDialog();
                return GetResult(mb);
            }
            /// <summary>
            /// 获取结果,通常和MessageBoxHelper.Create<T>配合使用
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="messageBox">MessageBoxHelper.Create<T>返回的对象</param>
            /// <returns>结果</returns>
            public static MessageBoxResult GetResult<T>(T messageBox) where T : Window, new()
            {
                var mc = messageBox.DataContext as MessageBoxDataContext;
                if (mc != null)
                {
                    return mc.Result;
                }
                return null;
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string context) where T : Window, new()
            {
                return Create<T>(null, context, "确定", null, null, null, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context) where T : Window, new()
            {
                return Create<T>(title, context, "确定", null, null, null, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context, string yesText) where T : Window, new()
            {
                return Create<T>(title, context, yesText, null, null, null, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context, string yesText, bool isCancelable) where T : Window, new()
            {
                return Create<T>(title, context, yesText, null, null, null, isCancelable);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context, string yesText, string noText) where T : Window, new()
            {
                return Create<T>(title, context, yesText, noText, null, null, false);
            }

            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context, string yesText, string noText, bool isCancelable) where T : Window, new()
            {
                return Create<T>(title, context, yesText, noText, null, null, isCancelable);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string context, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return Create<T>(null, context, null, null, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return Create<T>(null, context, yesText, noText, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <returns>消息框对象</returns>
            public static T Createg<T>(string title, string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown) where T : Window, new()
            {
                return Create<T>(title, context, yesText, noText, yestCountDown, noCountDown, false);
            }
            /// <summary>
            /// 创建消息框
            /// </summary>
            /// <typeparam name="T">绑定MessageBoxDataContext属性的窗口</typeparam>
            /// <param name="title">标题</param>
            /// <param name="context">显示内容</param>
            /// <param name="yesText">yes按钮的文本</param>
            /// <param name="noText">no按钮的文本</param>
            /// <param name="yestCountDown">yes按钮倒计时</param>
            /// <param name="noCountDown">no按钮倒计时</param>
            /// <param name="isCancelable">是否显示取消按钮</param>
            /// <returns>消息框对象</returns>
            public static T Create<T>(string title, string context, string yesText, string noText, TimeSpan? yestCountDown, TimeSpan? noCountDown, bool isCancelable) where T : Window, new()
            {
                T mb = new T();
                MessageBoxDataContext mc = new MessageBoxDataContext();
                bool isLegal = false;
                mb.DataContext = mc;
                mc.Title = title;
                mc.Context = context;
                mc.YesText = yesText;
                mc.NoText = noText;
                mc.YesLeftTime = yestCountDown;
                mc.NoLeftTime = noCountDown;
                mc.YesCommand = new Command((o) =>
                {
                    mc.Result = new MessageBoxResult() { Button = MessageBoxResultButton.Yes, YesLeftTime = mc.YesLeftTime, NoLeftTime = mc.NoLeftTime };
                    isLegal = true;
                    mb.Close();
                });
                mc.NoCommand = new Command((o) =>
                {
                    mc.Result = new MessageBoxResult() { Button = MessageBoxResultButton.No, YesLeftTime = mc.YesLeftTime, NoLeftTime = mc.NoLeftTime };
                    isLegal = true;
                    mb.Close();
                });
                if (isCancelable)
                {
                    mc.CancelCommand = new Command((o) =>
                    {
                        mc.Result = new MessageBoxResult() { Button = MessageBoxResultButton.Cancel, YesLeftTime = mc.YesLeftTime, NoLeftTime = mc.NoLeftTime };
                        isLegal = true;
                        mb.Close();
                    });
                }
                mb.Loaded += (s, e) =>
                {
                    if (mc.YesLeftTime != null || mc.NoLeftTime != null)
                    {
                        mc.Timer = new DispatcherTimer();
                        mc.Timer.Interval = TimeSpan.FromSeconds(1);
                        mc.Timer.Tick += (S, E) =>
                        {
                            if (mc.YesLeftTime != null)
                            {
                                mc.YesLeftTime = mc.YesLeftTime.Value.Add(-TimeSpan.FromSeconds(1));
                                if (mc.YesLeftTime.Value.TotalSeconds < 1)
                                {
                                    mc.Timer.Stop();
                                    mc.YesCommand.Execute(null);
                                }
                            }
                            if (mc.NoLeftTime != null)
                            {
                                mc.NoLeftTime = mc.NoLeftTime.Value.Add(-TimeSpan.FromSeconds(1));
                                if (mc.NoLeftTime.Value.TotalSeconds < 1)
                                {
                                    mc.Timer.Stop();
                                    mc.NoCommand.Execute(null);
                                }

                            }
                        };
                        mc.Timer.Start();
                    }
                };
                mb.Closing += (s, e) =>
                {
                    e.Cancel = !isLegal;
                };
                mb.Closed += (s, e) =>
                {
                    if (mc.Timer != null && mc.Timer.IsEnabled)
                    {
                        mc.Timer.Stop();
                    }
                };
                return mb;
            }
        }

    }
}
